package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Description: // 类说明，在创建类时要填写
 * @ClassName: TeachplanServiceImpl    // 类名，会自动填充
 * @Author: MYH          // 创建者
 * @Date: 2023/2/1 21:42   // 时间
 * @Version: 1.0     // 版本
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    private TeachplanMapper teachplanMapper;

    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;

    //查询课程计划（组成树形结构）
    @Override
    public List<TeachplanDto> findTeachplanTree(Long courseId) {

        return teachplanMapper.selectTreeNodes(courseId);
    }

    /**
     * 新增或修改课程计划
     *
     * @param teachplanDto
     * @return
     */
    @Override
    public TeachplanDto saveOrUpdateTeachplan(TeachplanDto teachplanDto) {

        Teachplan teachplan = teachplanMapper.selectById(teachplanDto.getId());
        if (teachplan != null) {//修改
            BeanUtils.copyProperties(teachplanDto, teachplan);
            teachplanMapper.updateById(teachplan);
        } else {//新增
            teachplan = new Teachplan();
            BeanUtils.copyProperties(teachplanDto, teachplan);
            //找到同级课程计划的数量
            int count = this.getTeachplanCount(teachplanDto.getCourseId(), teachplan.getParentid());
            //计算下默认的 orderby = count + 1
            teachplan.setOrderby(count + 1);
            teachplanMapper.insert(teachplan);
        }
        return teachplanDto;
    }

    //计算新课程计划的orderby,找到 同级 课程计划的数量
    private int getTeachplanCount(Long courseId, Long parentId) {

        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId, courseId);
        queryWrapper.eq(Teachplan::getParentid, parentId);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return count;
    }


    /**
     * 删除课程计划
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public List<TeachplanDto> deleteTeachplanDto(Long id) {

        Teachplan teachplan = teachplanMapper.selectById(id);
        //获取parentId,来进一步判断删除的是第一级别还是第二级别
        Long parentid = teachplan.getParentid();
        Long courseId = teachplan.getCourseId();
        if (parentid == 0) { //删除的是第一级别
            //查询该章下边有没有小节
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId, teachplan.getCourseId());
            queryWrapper.eq(Teachplan::getParentid, id);
            Integer integer = teachplanMapper.selectCount(queryWrapper);
            if (integer != 0) {   //该章下边有小节
                throw new XueChengPlusException("该章下边有小节，不能删除");
            } else { //该章下边没有小节，可删除
                teachplanMapper.deleteById(id);
                //删除课程计划后，同级别之间排序
                this.orderForDel(courseId,parentid);
            }
        } else { //删除的是第二级别
            //删除该小结
            teachplanMapper.deleteById(id);
            //删除该小结所对应的视频信息
            LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TeachplanMedia::getTeachplanId, id);
            teachplanMediaMapper.delete(queryWrapper);
            //删除课程计划后，同级别之间排序
            this.orderForDel(courseId,parentid);
        }
        return teachplanMapper.selectTreeNodes(teachplan.getCourseId());
    }


    /**
     * 删除课程计划后，同级别之间排序
     * @param courseId
     * @param parentid
     */
    private void orderForDel(Long courseId,Long parentid){
        //根据课程courseId,parent来查询同级别下的课程计划
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentid);
        List<Teachplan> teachplans = teachplanMapper.selectList(queryWrapper);
        //遍历集合，并修改orderBy字段的值
        int i = 0;
        for (Teachplan teachplan1 : teachplans) {
            i++;
            teachplan1.setOrderby(i);
            //进行数据持久化操作
            teachplanMapper.updateById(teachplan1);
        }
    }



    /**
     * 课程计划排序--上移
     *
     * @param id
     * @return
     */
    @Override
    public String moveupTeachplan(Long id) {

        Teachplan teachplan = teachplanMapper.selectById(id);
        //获取parent，来进一步确定是第一级别还是第二级别
        Long parentid = teachplan.getParentid();
        if (parentid == 0) { //第一级别
//            //判断要移动的课程计划是否处于首位
//            Integer orderby = teachplan.getOrderby();
//            if (orderby == 1){  //处于首位
//                throw new XueChengPlusException("该操作有误，请正确操作！");
//            }else { //处于非首位
//                //与上面的课程计划交换orderBy的值
//                //首先根据orderBy的值来获取上面的课程计划
//                LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
//                queryWrapper.eq(Teachplan::getOrderby,teachplan.getOrderby() - 1);
//                Teachplan teachplanUp = teachplanMapper.selectOne(queryWrapper);
//                //交换二者的orderBy的值
//                teachplan.setOrderby(teachplanUp.getOrderby());
//                teachplanUp.setOrderby(teachplan.getOrderby());
//                //保存到数据库
//                teachplanMapper.updateById(teachplan);
//                teachplanMapper.updateById(teachplanUp);
//        }
            int i = this.changeUpTeachplan(id);
            return i == 1 ? "操作成功" : "操作失败";
        } else { //第二级别
            int i = this.changeUpTeachplan(id);
            return i == 1 ? "操作成功" : "操作失败";
        }
    }

    //写一个交换两课程计划的接口，来供课程计划排序--上移使用
    private int changeUpTeachplan(Long id) {
        Teachplan teachplan = teachplanMapper.selectById(id);
        //判断要移动的课程计划是否处于首位
        Integer orderby = teachplan.getOrderby();
        if (orderby == 1) {  //处于首位
            throw new XueChengPlusException("该操作有误，请正确操作！");
        } else { //处于非首位
            //与上面的课程计划交换orderBy的值
            //首先根据orderBy的值来获取上面的课程计划
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId, teachplan.getCourseId());
            queryWrapper.eq(Teachplan::getParentid, teachplan.getParentid());
            queryWrapper.eq(Teachplan::getOrderby, teachplan.getOrderby() - 1);
            Teachplan teachplanUp = teachplanMapper.selectOne(queryWrapper);
            //交换二者的orderBy的值
            Integer temp = teachplan.getOrderby();
            teachplan.setOrderby(teachplanUp.getOrderby());
            teachplanUp.setOrderby(temp);
            //保存到数据库
            int i = teachplanMapper.updateById(teachplan);
            int i1 = teachplanMapper.updateById(teachplanUp);
            return (i + i1) == 2 ? 1 : 0;
        }
    }


    /**
     * 课程计划排序--下移
     *
     * @param id
     * @return
     */
    @Override
    public String movedownTeachplan(Long id) {

        Teachplan teachplan = teachplanMapper.selectById(id);
        //获取parent，来进一步确定是第一级别还是第二级别
        Long parentid = teachplan.getParentid();
        if (parentid == 0) {    //第一级别
            int i = this.changeDownTeachplan(id);
            return i == 1 ? "操作成功" : "操作失败";
        } else { //第二级别
            int i = this.changeDownTeachplan(id);
            return i == 1 ? "操作成功" : "操作失败";
        }
    }

    //写一个交换两课程计划的接口，来供课程计划排序--下移使用
    private int changeDownTeachplan(Long id) {

        Teachplan teachplan = teachplanMapper.selectById(id);

        //先查询同级别下 有多少个课程计划
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getCourseId,teachplan.getCourseId());
        wrapper.eq(Teachplan::getParentid,teachplan.getParentid());
        Integer count = teachplanMapper.selectCount(wrapper);

        //判断要移动的课程计划是否处于尾位
        Integer orderby = teachplan.getOrderby();
        if (orderby == count) {  //处于尾位
            throw new XueChengPlusException("该操作有误，请正确操作！");
        } else { //处于非尾位
            //与下面的课程计划交换orderBy的值
            //首先根据orderBy的值来获取下面的课程计划
            LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Teachplan::getCourseId, teachplan.getCourseId());
            queryWrapper.eq(Teachplan::getParentid, teachplan.getParentid());
            queryWrapper.eq(Teachplan::getOrderby, teachplan.getOrderby() + 1);
            Teachplan teachplanUp = teachplanMapper.selectOne(queryWrapper);
            //交换二者的orderBy的值
            Integer temp = teachplan.getOrderby();
            teachplan.setOrderby(teachplanUp.getOrderby());
            teachplanUp.setOrderby(temp);
            //保存到数据库
            int i = teachplanMapper.updateById(teachplan);
            int i1 = teachplanMapper.updateById(teachplanUp);
            return (i + i1) == 2 ? 1 : 0;
        }
    }


    /**
     * 课程计划和媒资的绑定
     * @param bindTeachplanMediaDto
     * @return
     */
    @Override
    @Transactional
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {

        //获取教学计划的id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        //通过id来查询教学计划
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        //约束的校验
        //教学计划不存在也无法绑定
        if (teachplan == null){
            XueChengPlusException.cast("教学计划不存在,无法绑定");
        }
        //只有二级目录才可以绑定视频
        Integer grade = teachplan.getGrade();
        if (grade != 2){
            XueChengPlusException.cast("只有二级目录才可以绑定媒资文件");
        }

        //删除原来的记录
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
        teachplanMediaMapper.delete(queryWrapper);

        //添加新记录
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    @Override
    public void delAssociationMedia(Long teachplanId, String mediaId) {
        LambdaQueryWrapper<TeachplanMedia> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
        queryWrapper.eq(TeachplanMedia::getMediaId,mediaId);
        teachplanMediaMapper.delete(queryWrapper);
    }
}
